package com.threez.common.dubbo.filter;

import com.threez.common.dubbo.domain.DubboResp;
import com.threez.core.exception.GlobalException;
import com.threez.core.exception.enums.GlobalExceptionEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;

import javax.validation.ValidationException;

/**
 * dubbo日志过滤器
 *
 * @author cl-team
 */
@Slf4j
@Activate(group = {CommonConstants.PROVIDER, CommonConstants.CONSUMER}, order = 13)
public class DubboExceptionFilter implements Filter {

    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {

        // 执行接口调用逻辑
        try {
            Result result = invoker.invoke(invocation);
            // 如果发生异常 则打印异常日志
            if (result.hasException()) {
                Throwable exception = result.getException();
                if (exception instanceof GlobalException) {
                    GlobalException globalException = (GlobalException) exception;
                    log.error("dubbo过滤-自定义GlobalException异常：{} - {}", globalException.getCode(), globalException.getMessage());
                    result.setValue(DubboResp.fail(globalException.getCode(), globalException.getMessage(), globalException.getErrorData()));
                    result.setException(null);
                } else if (exception instanceof ValidationException) {
                    ValidationException violationException = (ValidationException) exception;
                    String message = violationException.getMessage();
                    log.error("dubbo过滤-入参请求错误信息是：{}", message);
                    result.setValue(DubboResp.fail(GlobalExceptionEnum.PARAM_ERROR, "dubbo 调用入参不Validation合规"));
                    result.setException(null);

                } else {
                    log.error("dubbo过滤-自定义GlobalException异常：", exception);
                    result.setValue(DubboResp.fail(GlobalExceptionEnum.SERVICE_FACADE_ERROR));
                    result.setException(null);
                }

            }
            return result;
        } catch (Exception e) {
            log.error("dubbo服务调用发生异常", e);
            //AsyncRpcResult
//            AppResponse
            throw e;
        }

    }

}
